﻿using WebApp.BLL.Manage;
using WebApp.Common;
using WebApp.Models;
using WebApp.ViewModels;
using Newtonsoft.Json.Linq;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using WebApp.BLL;

namespace WebApp.BLL
{
    public class CommonStr
    {
        #region Ver
        public static string Ver
        {
            get
            {
                //var ver = Utils.NvStr(ConfigurationManager.AppSettings["resource.version"]);
                var ver = new S_environmentService().GetValue("resource.version");
                if (string.IsNullOrEmpty(ver))
                {
                    return DateTime.Now.Ticks.ToString();
                }
                else
                {
                    return ver;
                }
            }
        }
        #endregion

        #region SysTitle

        public static string SysTitle
        {
            get
            {
                return new S_environmentService().GetValue("system.title");
            }
        }

        #endregion

        #region GetLangSelectList

        public static SelectList GetLangSelectList(string selectedValue = "")
        {
            Dictionary<string, string> list = new Dictionary<string, string>();
            list.Add("zh_cn", "简体中文");
            list.Add("zh_hk", "繁体中文");

            return new SelectList(list, "Key", "Value", selectedValue);
        }

        #endregion

        #region GetDictName

        public static string GetDictName(string typecode, string code)
        {
            return new S_dictService().GetName(typecode, code);
        }

        #endregion

        #region GetUserName

        public static string GetUserName(int? userid)
        {
            return new S_userService().GetUserRealname(userid);
        }

        #endregion

        #region EnumToSelectList

        public static SelectList EnumToSelectList(Type enumtype, string selectedValue = "")
        {
            List<DictionaryEntry> list = new List<DictionaryEntry>();

            string[] values = Enum.GetNames(enumtype);
            for (int i = 0; i < values.Length; i++)
            {
                list.Add(new DictionaryEntry(((int)Enum.Parse(enumtype, values[i])).ToString(), Enum.Parse(enumtype, values[i]).ToString()));
            }

            return new SelectList(list, "Key", "Value", selectedValue);
        }

        #endregion

        #region EnumNameToSelectList

        public static SelectList EnumNameToSelectList(Type enumtype, string selectedValue = "")
        {
            List<DictionaryEntry> list = new List<DictionaryEntry>();

            string[] values = Enum.GetNames(enumtype);
            for (int i = 0; i < values.Length; i++)
            {
                list.Add(new DictionaryEntry(Enum.Parse(enumtype, values[i]).ToString(), Enum.Parse(enumtype, values[i]).ToString()));
            }

            return new SelectList(list, "Key", "Value", selectedValue);
        }

        #endregion

        #region GetDateStr

        /// <summary>
        /// 获取格式化过的日期字符串
        /// </summary>
        /// <param name="date"></param>
        /// <param name="formatstr"></param>
        /// <returns></returns>
        public static string GetDateStr(DateTime? date, string formatstr = "yyyy-MM-dd")
        {
            if (date.HasValue)
                return date.Value.ToString(formatstr);
            else
                return string.Empty;
        }

        /// <summary>
        /// 获取格式化过的日期+时间字符串
        /// </summary>
        /// <param name="date"></param>
        /// <param name="formatstr"></param>
        /// <returns></returns>
        public static string GetDateTimeStr(DateTime? date, string formatstr = "yyyy-MM-dd HH:mm:ss")
        {
            if (date.HasValue)
                return date.Value.ToString(formatstr);
            else
                return string.Empty;
        }

        #endregion

        #region TryGetdate

        public static DateTime? TryGetdate(string datestr)
        {
            if (string.IsNullOrEmpty(datestr))
            {
                return null;
            }
            else if ("@now".Equals(datestr, StringComparison.OrdinalIgnoreCase))
            {
                return DateTime.Now;
            }
            else
            {
                DateTime d;
                if (DateTime.TryParse(datestr, out d))
                {
                    return d;
                }
                else
                {
                    return null;
                }
            }
        }

        #endregion

        #region TryGetdecimal

        public static decimal? TryGetdecimal(string valuestr)
        {
            if (string.IsNullOrEmpty(valuestr))
            {
                return null;
            }
            else
            {
                decimal d;
                if (decimal.TryParse(valuestr, out d))
                {
                    return d;
                }
                else
                {
                    return null;
                }
            }
        }

        #endregion

        #region TryGetinteger

        public static int? TryGetinteger(string valuestr)
        {
            if (string.IsNullOrEmpty(valuestr))
            {
                return null;
            }
            else
            {
                int d;
                if (int.TryParse(valuestr, out d))
                {
                    return d;
                }
                else
                {
                    return null;
                }
            }
        }

        #endregion

        #region 检查密码是否符合规则

        /// <summary>
        /// 检查密码是否符合规则：
        /// 要求至少6位，并且必须是数字加字符的组合
        /// </summary>
        /// <param name="password"></param>
        /// <returns></returns>
        public static string CheckPasswordRule(string password)
        {
            if (password == null) { return "no"; }
            if (password.Length < 6 || password.Length >16)
            {
                //您的密码必须是6~16位的字符，且至少包含一个数字和一个字母。可以使用特殊符号，字母区分大小写！
                return "您的密码必须是6~16位的字符，且必须是数字和字母的组合。可以使用特殊符号，字母区分大小写！";
            }

            EnumCharFlag flag = GetPasswordStrong(password);
            if ((flag & EnumCharFlag.Number) == EnumCharFlag.Number
                && (flag & EnumCharFlag.Character) == EnumCharFlag.Character)
            {
                return "ok";
            }
            else if ((flag & EnumCharFlag.Number) == EnumCharFlag.Number
               && (flag & EnumCharFlag.SpecialCharacter) == EnumCharFlag.SpecialCharacter)
            {
                return "ok";
            }
            else
            {
                return "您的密码必须是6~16位的字符，且必须是数字和字母的组合。可以使用特殊符号，字母区分大小写！";
            }
        }

        #endregion

        #region 密码强度验证

        /// <summary>
        /// 判断密码强度
        /// </summary>
        /// <param name="password"></param>
        /// <returns></returns>
        public static EnumCharFlag GetPasswordStrong(string password)
        {
            EnumCharFlag flag = 0;

            foreach (char c in password)
            {
                flag = flag | CharMode(c);
            }

            return flag;
        }

        /// <summary> 
        /// 检查字符是属于哪一类 
        /// </summary> 
        /// <param name="_in"></param> 
        /// <returns></returns> 
        private static EnumCharFlag CharMode(char _in)
        {
            if (_in >= 48 && _in <= 57) // 数字   
                return EnumCharFlag.Number;
            if (_in >= 65 && _in <= 90) // 大写字母  
                return EnumCharFlag.Character;
            if (_in >= 97 && _in <= 122) // 小写   
                return EnumCharFlag.Character;
            else
                return EnumCharFlag.SpecialCharacter; // 特殊字符
        }

        #endregion

        #region 获取客户端 ip

        public static string getIPAddress(HttpContext context)
        {
            string result = String.Empty;
            //context.CurrentH
            result = context.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];

            // 如果使用代理，获取真实IP 
            if (result != null && result.IndexOf(".") == -1)    //没有“.”肯定是非IPv4格式 
                result = null;
            else if (result != null)
            {
                if (result.IndexOf(",") != -1)
                {
                    //有“,”，估计多个代理。取第一个不是内网的IP。 
                    result = result.Replace(" ", "").Replace("'", "");
                    string[] temparyip = result.Split(",;".ToCharArray());
                    for (int i = 0; i < temparyip.Length; i++)
                    {
                        if (IsIPAddress(temparyip[i])
                            && temparyip[i].Substring(0, 3) != "10."
                            && temparyip[i].Substring(0, 7) != "192.168"
                            && temparyip[i].Substring(0, 7) != "172.16.")
                        {
                            return temparyip[i];    //找到不是内网的地址 
                        }
                    }
                }
                else if (IsIPAddress(result)) //代理即是IP格式 
                    return result;
                else
                    result = null;    //代理中的内容 非IP，取IP 
            }
            if (null == result || result == String.Empty)
            {
                result = context.Request.ServerVariables["REMOTE_ADDR"];
                if (result == "::1") { result = "127.0.0.1"; }
            }

            if (result == null || result == String.Empty)
                result = context.Request.UserHostAddress;

            return result;
        }
        /// <summary>
        /// 判断是否是IP地址格式 0.0.0.0
        /// </summary>
        /// <param name="str1">待判断的IP地址</param>
        /// <returns>true or false</returns>
        private static bool IsIPAddress(string str1)
        {
            if (str1 == null || str1 == string.Empty || str1.Length < 7 || str1.Length > 15) return false;

            string regformat = @"^\d{1,3}[\.]\d{1,3}[\.]\d{1,3}[\.]\d{1,3}$";

            Regex regex = new Regex(regformat, RegexOptions.IgnoreCase);
            return regex.IsMatch(str1);
        }

        #endregion

        #region 根据姓名获取拼音代码（4位规则）

        public static string GetPatcode(string patname)
        {
            patname = Utils.NvStr(patname);

            StringBuilder sb = new StringBuilder();

            if (patname.Length <= 2)
            {
                foreach (char c in patname)
                {
                    var py = Utils.GetAllPYLetters(c.ToString()).ToUpper();
                    sb.Append(py.Length <= 1 ? py : py.Substring(0, 2));
                }
            }
            else if (patname.Length == 3)
            {
                var py = Utils.GetAllPYLetters(patname[0].ToString()).ToUpper();
                sb.Append(py.Length < 1 ? py : py.Substring(0, 1));

                py = Utils.GetAllPYLetters(patname[1].ToString()).ToUpper();
                sb.Append(py.Length < 1 ? py : py.Substring(0, 1));

                py = Utils.GetAllPYLetters(patname[2].ToString()).ToUpper();
                sb.Append(py.Length <= 1 ? py : py.Substring(0, 2));
            }
            else
            {
                var py = Utils.GetAllPYLetters(patname[0].ToString()).ToUpper();
                sb.Append(py.Length < 1 ? py : py.Substring(0, 1));

                py = Utils.GetAllPYLetters(patname[1].ToString()).ToUpper();
                sb.Append(py.Length < 1 ? py : py.Substring(0, 1));

                py = Utils.GetAllPYLetters(patname[2].ToString()).ToUpper();
                sb.Append(py.Length < 1 ? py : py.Substring(0, 1));

                py = Utils.GetAllPYLetters(patname[3].ToString()).ToUpper();
                sb.Append(py.Length < 1 ? py : py.Substring(0, 1));
            }

            return sb.ToString();
        }

        #endregion

        #region 根据身份证号获取生日

        /// <summary>
        /// 根据身份证号获取生日
        /// </summary>
        /// <param name="cardno"></param>
        /// <returns></returns>
        public static Nullable<DateTime> GetCardBirthday(string cardno)
        {
            string datestr = "";

            if (cardno.Length == 18)
            {
                datestr = cardno.Substring(6, 4) + "-" + cardno.Substring(10, 2) + "-" + cardno.Substring(12, 2);
            }
            else if (cardno.Length == 15)
            {
                datestr = "19" + cardno.Substring(6, 2) + "-" + cardno.Substring(8, 2) + "-" + cardno.Substring(10, 2);
            }

            DateTime d;
            if (DateTime.TryParse(datestr, out d))
            {
                return d.Date;
            }
            else
            {
                return new Nullable<DateTime>();
            }
        }

        #endregion

        #region 根据身份证号获取性别

        /// <summary>
        /// 根据身份证号获取性别
        /// </summary>
        /// <param name="cardno"></param>
        /// <returns></returns>
        public static string GetCardGender(string cardno)
        {
            string gendercode = "";

            if (cardno.Length == 18)
            {
                //18位身份证号，其中17位表示性别（奇数：男，偶数：女）
                gendercode = cardno.Substring(16, 1);
            }
            else if (cardno.Length == 15)
            {
                //15位身份证号，最后一位表示性别（奇数：男，偶数：女）
                gendercode = cardno.Substring(14, 1);
            }

            if (gendercode != "")
            {
                if (Utils.NvInt(gendercode) % 2 == 0)
                {
                    return enmGender.女.ToString("d");
                }
                else
                {
                    return enmGender.男.ToString("d");
                }
            }
            else
            {
                return "";
            }
        }

        #endregion

        #region 计算年龄（周岁）

        /// <summary>
        /// 计算年龄（周岁）
        /// </summary>
        /// <param name="birthday"></param>
        /// <returns></returns>
        public static int GetAge(Nullable<DateTime> birthday)
        {
            return GetAge(birthday, DateTime.Now);
        }

        public static string GetAge(string birthday)
        {
            if ("".Equals(birthday))
            {
                return "";
            }
            else
            {
                return GetAge(Convert.ToDateTime(birthday)).ToString();
            }
        }

        public static int GetAge(Nullable<DateTime> birthday, Nullable<DateTime> enddate)
        {
            if (!birthday.HasValue || !enddate.HasValue)
            {
                return 0;
            }
            if (birthday.Value == DateTime.MinValue || birthday.Value <= Convert.ToDateTime("1900-1-1"))
            {
                return 0;
            }

            int age = enddate.Value.Year - birthday.Value.Year;

            if (birthday.Value.Date.AddYears(age) > enddate.Value.Date)
            {
                return age - 1;
            }
            else
            {
                return age;
            }
        }

        #endregion

        #region GetMobileStr

        public static string GetMobileStr(string mobile)
        {
            if (Utils.NvStr(mobile).Length == 11)
            {
                return mobile.Substring(0, 3) + "****" + mobile.Substring(7, 4);
            }
            else if (Utils.NvStr(mobile).Length >= 7)
            {
                return mobile.Substring(0, mobile.Length - 4) + "****";
            }
            else
            {
                return mobile;
            }
        }

        #endregion

        #region GetFormattedFieldid

        /// <summary>
        /// 格式化数据库字段ID（仅首字母大写，其它全小写）
        /// </summary>
        /// <param name="fieldid"></param>
        /// <returns></returns>
        public static string GetFormattedFieldid(string fieldid)
        {
            fieldid = Utils.NvStr(fieldid).Trim();
            if (fieldid.Length <= 1)
            {
                return fieldid.ToUpper();
            }
            else
            {
                return fieldid.Substring(0, 1).ToUpper() + fieldid.Substring(1).ToLower();
            }
        }

        #endregion

        #region 枚举型转换为List(DictionaryEntry)

        /// <summary>
        /// 枚举型转换为List(DictionaryEntry)
        /// </summary>
        /// <param name="enumtype"></param>
        /// <returns></returns>
        public static List<DictionaryEntry> EnumToList(Type enumtype)
        {
            List<DictionaryEntry> list = new List<DictionaryEntry>();

            string[] values = Enum.GetNames(enumtype);
            for (int i = 0; i < values.Length; i++)
            {
                list.Add(new DictionaryEntry(((int)Enum.Parse(enumtype, values[i])).ToString(), Enum.Parse(enumtype, values[i]).ToString()));
            }

            return list;
        }

        #endregion

        #region 获取枚举中文名称
        /// <summary>
        /// 获取枚举中文名称
        /// </summary>
        /// <param name="date"></param>
        /// <param name="formatstr"></param>
        /// <returns></returns>
        public static string GetEnumName(Type type, int value)
        {
            var name = Enum.GetName(type, value);

            return Utils.NvStr(name);
        }
        #endregion
    }
}
